/********************************************************************
	File		: CountPtr.h
	Created		: 2011-2-21	23:25
	Author		: Wjl

	Desc		: This file is part of omiga 2d engine.
*********************************************************************/

#ifndef CountPtr_H__
#define CountPtr_H__

namespace Core
{
	template <class T>
	class CountPtr
	{
	public:

		CountPtr(T* _p = 0) : m_pCounter(0)
		{
			if (_p)
			{
				m_pCounter = new Counter(_p, 1);
			}
		}

		CountPtr(const CountPtr& _other)
		{
			Aquire(_other.m_pCounter);
		}

		virtual ~CountPtr()
		{
			Release();
		}

		CountPtr& operator = (const CountPtr& _other)
		{
			if (this != &_other)
			{
				Release();
				Aquire(_other.m_pCounter);
			}
			return *this;
		}

		bool	operator == (const CountPtr& _other) const
		{
			return m_pCounter? m_pCounter == _other.m_pCounter: false;
		}

		T&		operator * () const { return *m_pCounter->ptr; }
		T*		operator -> () const { return m_pCounter->ptr; }
		T*		Get() const { return m_pCounter? m_pCounter->ptr : 0; }
		
		unsigned int 	GetCount() const { return m_pCounter? m_pCounter->count : 0; }

	private:

		struct Counter
		{
			T*				ptr;
			unsigned int	count;

			Counter(T* _ptr = 0, unsigned int _count = 0) : ptr(_ptr), count(_count) {}
		}* m_pCounter;

		void	Aquire(Counter*	_c)
		{
			m_pCounter = _c;
			if (m_pCounter)
			{
				++_c->count;
			}
		}

		void	Release()
		{
			if (m_pCounter)
			{
				if (--m_pCounter->count == 0)
				{
					delete m_pCounter->ptr;
					delete m_pCounter;
				}
				m_pCounter = 0;
			}
		}
	};
}

#endif // CountPtr_H__